package com.yvan.leto;

import com.google.common.base.Strings;
import com.yvan.Conv;
import com.yvan.IpUtils;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

@Slf4j
class AppConfig {

    private static final String SERVER_PROPERTIES_LINUX = "/opt/leto/settings.properties";
    private static final String SERVER_PROPERTIES_WINDOWS = "C:/opt/leto/settings.properties";

    private static final String LETO_ENV = "./leto-env.properties";
    private static final String LETO = "./META-INF/leto.properties";
    private static final String DEFAULT_LETO_SERVER = "http://leto_server";

    private static final String CFG_LETO_SERVER = "server";
    private static final String CFG_ENV = "env";
    private static final String CFG_CLIENT_ID = "clientid";
    private static final String CFG_CACHE_ENABLE = "cache_enable";
    private static final String CFG_CACHE_PATH = "cache_path";
    private static final String CFG_APP = "app";
    private static final String CFG_ENABLE = "enable";
    private static final String CFG_ENABLE_WATCH_CHANGE = "enable_watch_change";

    /**
     * 应用编号
     */
    final String appId;

    /**
     * 是否开启leto, 默认 true
     */
    final boolean enable;

    /**
     * 是否开启leto watch config change, 默认 true
     */
    final boolean enableWatchChange;

    /**
     * 环境标识
     */
    final String env;

    /**
     * 配置中心地址
     */
    final String letoServer;

    /**
     * 配置文件是否缓存到本地, 默认 true
     */
    final boolean cacheEnable;

    /**
     * 缓存路径，默认当前目录
     */
    final String cachePath;

    /**
     * 客户端编号
     */
    String clientId;

    AppConfig() {
        final String envFile = IpUtils.isOSWindows() ? SERVER_PROPERTIES_WINDOWS : SERVER_PROPERTIES_LINUX;

        //载入配置文件
        Properties prop = new Properties();

        try {
            @Cleanup FileInputStream fi = new FileInputStream(envFile);
            prop.load(fi);
        } catch (IOException e) {
            log.error("load " + envFile, e);
        }
        prop = ResourceUtils.readConfigFile(LETO_ENV, prop);
        Properties env = System.getProperties();

        //定义全局配置中心地址
        String defaultLetoServer = env.getProperty(CFG_LETO_SERVER, prop.getProperty(CFG_LETO_SERVER, DEFAULT_LETO_SERVER));

        //获取当前环境标识
        this.env = env.getProperty(CFG_ENV, prop.getProperty(CFG_ENV, ""));
        if (Strings.isNullOrEmpty(this.env)) {
            //env 不允许为空
            throw new RuntimeException(CFG_ENV + " is null!");
        }

        //获取当前 clientId
        this.clientId = env.getProperty(CFG_CLIENT_ID, prop.getProperty(CFG_CLIENT_ID, ""));
        if (Strings.isNullOrEmpty(this.clientId)) {
            //clientid 不允许为空
            throw new RuntimeException(CFG_CLIENT_ID + " is null!");
        }

        //取当前配置中心地址
        final String envMetaServer = CFG_LETO_SERVER + "." + this.env;
        this.letoServer = env.getProperty(envMetaServer, prop.getProperty(envMetaServer, defaultLetoServer));
        if (Strings.isNullOrEmpty(this.env)) {
            //letoServer 不允许为空
            throw new RuntimeException(envMetaServer + " is null!");
        }

        //配置文件是否缓存到本地
        this.cacheEnable = Conv.NB(env.getProperty(CFG_CACHE_ENABLE, prop.getProperty(CFG_CACHE_ENABLE, "true")));

        //缓存路径，默认当前目录
        this.cachePath = Conv.NS(env.getProperty(CFG_CACHE_PATH, prop.getProperty(CFG_CACHE_PATH, "./")));

        // leto.properti 文件
        Properties propApp = new Properties();
        propApp = ResourceUtils.readConfigFile(LETO, propApp);
        //APP名称
        this.appId = Conv.NS(env.getProperty(CFG_APP, propApp.getProperty(CFG_APP, "")));
        if (Strings.isNullOrEmpty(appId)) {
            //AppId不允许为空
            throw new RuntimeException("appId is null!");
        }

        //开启开关
        this.enable = Conv.NB(env.getProperty(CFG_ENABLE, propApp.getProperty(CFG_ENABLE, "true")));

        //开启关注配置更新
        this.enableWatchChange = Conv.NB(env.getProperty(CFG_ENABLE_WATCH_CHANGE, propApp.getProperty(CFG_ENABLE_WATCH_CHANGE, "true")));
    }

    public boolean isEnable(){
        return this.enable;
    }

    public boolean isEnableWatchChange(){
        return this.enableWatchChange;
    }
}
